package mx.ipn.persistencia.mysql;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Time;
import java.util.ArrayList;

import mx.ipn.persistencia.FabricaDeDAOs;
import mx.ipn.persistencia.dao.BitacoraAccesoDAO;
import mx.ipn.persistencia.dao.MotivoDAO;
import mx.ipn.persistencia.dao.UsuarioDAO;
import mx.ipn.to.BitacoraAccesoTO;
import mx.ipn.to.UsuarioTO;
import mx.ipn.to.MotivoTO;
import mx.ipn.to.FechaHoraTO;

public class BitacoraAccesoDAOMySQL implements BitacoraAccesoDAO {
	static {
		FabricaDeDAOsMySQL.iniciaLog(BitacoraAccesoDAOMySQL.class);
	}

	private static final String INSERT = "INSERT INTO bitacora_acceso (fecha,hora,id_usuario,id_motivo) VALUES(?,?,?,?)";
	private static final String UPDATE = "UPDATE bitacora_acceso SET fecha=?,hora=?,id_usuario=?,id_motivo=? WHERE id_operacion=?";

	private static final String FINDBYID = "SELECT * FROM bitacora_acceso WHERE id_operacion=?";

	private static final String FINDBYIDOPERACIOFECHANUSUARIOMOTIVO = "SELECT * FROM bitacora_acceso WHERE id_operacion>=? AND fecha>=? AND id_usuario=? AND id_motivo=?";

	private static final String SELECT = "SELECT * FROM bitacora_acceso";
	private static final String SELECTBYRANGOFECHA = "SELECT * FROM bitacora_acceso WHERE fecha>=? AND fecha<=?";
	private static final String SELECTBYRANGOFECHAHORA = "SELECT * FROM bitacora_acceso WHERE fecha>=? AND fecha<=? AND hora>=? AND hora<=?";

	private static final String SELECTBYUSUARIO = "SELECT * FROM bitacora_acceso WHERE id_usuario=?";
	private static final String SELECTBYMOTIVO = "SELECT * FROM bitacora_acceso WHERE id_motivo=?";
	private static final String SELECTBYUSUARIOMOTIVORANGOFECHAHORA = "SELECT * FROM bitacora_acceso WHERE id_usuario=? AND id_motivo=? AND fecha>=? AND fecha<=? AND hora>=? AND hora<=?";

	@Override
	public BitacoraAccesoTO findBitacoraAccesoById(int idOperacion) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYID);

			ps.setInt(1, idOperacion);

			ResultSet rs = ps.executeQuery();
			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			UsuarioDAO usuarioDAO = fabricaMySQL.getUsuarioDAO();
			MotivoDAO motivoDAO = fabricaMySQL.getMotivoDAO();

			if (rs.next()) {
				idOperacion = rs.getInt("id_operacion");
				java.sql.Date fecha = rs.getDate("fecha");
				java.sql.Time hora = rs.getTime("hora");

				ArrayList<UsuarioTO> listUsuarioTO = new ArrayList<UsuarioTO>();
				ArrayList<MotivoTO> listMotivoTO = new ArrayList<MotivoTO>();
				UsuarioTO usuarioTO = usuarioDAO.findUsuarioById(rs
						.getInt("id_usuario"));
				MotivoTO motivoTO = motivoDAO.findMotivoById(rs
						.getInt("id_motivo"));
				listUsuarioTO.add(usuarioTO);
				listMotivoTO.add(motivoTO);

				UsuarioTO[] arrUsuarioTO = (UsuarioTO[]) listUsuarioTO
						.toArray(new UsuarioTO[listUsuarioTO.size()]);
				MotivoTO[] arrMotivoTO = (MotivoTO[]) listMotivoTO
						.toArray(new MotivoTO[listMotivoTO.size()]);

				BitacoraAccesoTO bitacoraAccesoTO = new BitacoraAccesoTO(
						idOperacion, fecha, hora, arrUsuarioTO, arrMotivoTO);
				ps.close();
				conexion.close();
				return bitacoraAccesoTO;
			}
			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public BitacoraAccesoTO findBitacoraAccesoByIdUsuarioMotivo(
			int idBitacoraAcceso,java.sql.Date fechaInicio, int idUsuario, int idMotivo) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYIDOPERACIOFECHANUSUARIOMOTIVO);

			ps.setInt(1, idBitacoraAcceso);
			ps.setDate(2, fechaInicio);
			ps.setInt(3, idUsuario);
			ps.setInt(4, idMotivo);
			ResultSet rs = ps.executeQuery();

			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			UsuarioDAO usuarioDAO = fabricaMySQL.getUsuarioDAO();
			MotivoDAO motivoDAO = fabricaMySQL.getMotivoDAO();

			if (rs.next()) {
				idBitacoraAcceso = rs.getInt("id_operacion");
				java.sql.Date fecha = rs.getDate("fecha");
				java.sql.Time hora = rs.getTime("hora");

				ArrayList<UsuarioTO> listUsuarioTO = new ArrayList<UsuarioTO>();
				ArrayList<MotivoTO> listMotivoTO = new ArrayList<MotivoTO>();
				UsuarioTO usuarioTO = usuarioDAO.findUsuarioById(rs
						.getInt("id_usuario"));
				MotivoTO motivoTO = motivoDAO.findMotivoById(rs
						.getInt("id_motivo"));
				listUsuarioTO.add(usuarioTO);
				listMotivoTO.add(motivoTO);

				UsuarioTO[] arrUsuarioTO = (UsuarioTO[]) listUsuarioTO
						.toArray(new UsuarioTO[listUsuarioTO.size()]);
				MotivoTO[] arrMotivoTO = (MotivoTO[]) listMotivoTO
						.toArray(new MotivoTO[listMotivoTO.size()]);

				BitacoraAccesoTO bitacoraAccesoTO = new BitacoraAccesoTO(
						idBitacoraAcceso, fecha, hora, arrUsuarioTO, arrMotivoTO);
				ps.close();
				conexion.close();
				return bitacoraAccesoTO;
			}
			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public boolean insertBitacoraAcceso(BitacoraAccesoTO bitacoraAccesoTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(INSERT);

			ps.setDate(1, FechaHoraTO.getFecha(bitacoraAccesoTO.getFecha()));
			ps.setTime(2, FechaHoraTO.getHora(bitacoraAccesoTO.getHora()));
			ps.setInt(3, bitacoraAccesoTO.getIdUsuario());
			ps.setInt(4, bitacoraAccesoTO.getIdMotivo());

			ps.executeUpdate();

			ps.close();
			conexion.close();

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public ArrayList<BitacoraAccesoTO> selectBitacoraAcceso() {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(SELECT);

			ResultSet rs = ps.executeQuery();
			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			UsuarioDAO usuarioDAO = fabricaMySQL.getUsuarioDAO();
			MotivoDAO motivoDAO = fabricaMySQL.getMotivoDAO();

			ArrayList<BitacoraAccesoTO> coleccion = null;

			while (rs.next()) {
				if (coleccion == null)
					coleccion = new ArrayList<BitacoraAccesoTO>();

				int idOperacion = rs.getInt("id_operacion");
				java.sql.Date fecha = rs.getDate("fecha");
				java.sql.Time hora = rs.getTime("hora");

				ArrayList<UsuarioTO> listUsuarioTO = new ArrayList<UsuarioTO>();
				ArrayList<MotivoTO> listMotivoTO = new ArrayList<MotivoTO>();
				UsuarioTO usuarioTO = usuarioDAO.findUsuarioById(rs
						.getInt("id_usuario"));
				MotivoTO motivoTO = motivoDAO.findMotivoById(rs
						.getInt("id_motivo"));
				listUsuarioTO.add(usuarioTO);
				listMotivoTO.add(motivoTO);

				UsuarioTO[] arrUsuarioTO = (UsuarioTO[]) listUsuarioTO
						.toArray(new UsuarioTO[listUsuarioTO.size()]);
				MotivoTO[] arrMotivoTO = (MotivoTO[]) listMotivoTO
						.toArray(new MotivoTO[listMotivoTO.size()]);

				BitacoraAccesoTO bitacoraAccesoTO = new BitacoraAccesoTO(
						idOperacion, fecha, hora, arrUsuarioTO, arrMotivoTO);

				coleccion.add(bitacoraAccesoTO);
			}
			ps.close();
			conexion.close();

			return coleccion;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public BitacoraAccesoTO selectByMotivo(int idMotivo) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			UsuarioDAO usuarioDAO = null;
			MotivoDAO motivoDAO = null;

			ArrayList<Integer> listIdOperacion = null;
			ArrayList<java.sql.Date> listFecha = null;
			ArrayList<java.sql.Time> listHora = null;
			ArrayList<UsuarioTO> listUsuarioTO = null;
			ArrayList<MotivoTO> listMotivoTO = null;

			BitacoraAccesoTO bitacoraAccesoTO = null;

			PreparedStatement ps = conexion.prepareStatement(SELECTBYMOTIVO);
			ps.setInt(1, idMotivo);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (listIdOperacion == null) {

					listIdOperacion = new ArrayList<Integer>();
					listFecha = new ArrayList<java.sql.Date>();
					listHora = new ArrayList<java.sql.Time>();
					listUsuarioTO = new ArrayList<UsuarioTO>();
					listMotivoTO = new ArrayList<MotivoTO>();

					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					usuarioDAO = fabricaMySQL.getUsuarioDAO();
					motivoDAO = fabricaMySQL.getMotivoDAO();
				}
				listIdOperacion.add(rs.getInt("id_operacion"));
				listFecha.add(rs.getDate("fecha"));
				listHora.add(rs.getTime("hora"));
				listUsuarioTO.add(usuarioDAO.findUsuarioById(rs
						.getInt("id_usuario")));
			}
			if (listIdOperacion != null) {
				listMotivoTO.add(motivoDAO.findMotivoById(idMotivo));

				UsuarioTO[] arrUsuarioTO = (UsuarioTO[]) listUsuarioTO
						.toArray(new UsuarioTO[listUsuarioTO.size()]);
				MotivoTO[] arrMotivoTO = (MotivoTO[]) listMotivoTO
						.toArray(new MotivoTO[listMotivoTO.size()]);
				Date[] arrFecha = (Date[]) listFecha.toArray(new Date[listFecha
						.size()]);
				Time[] arrHora = (Time[]) listHora.toArray(new Time[listHora
						.size()]);
				Integer[] arrIdOperacion = (Integer[]) listIdOperacion
						.toArray(new Integer[listIdOperacion.size()]);

				bitacoraAccesoTO = new BitacoraAccesoTO(arrIdOperacion,
						arrFecha, arrHora, arrUsuarioTO, arrMotivoTO);
			}
			ps.close();
			conexion.close();
			return bitacoraAccesoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public ArrayList<BitacoraAccesoTO> selectByRangoFecha(Date inicio, Date fin) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion
					.prepareStatement(SELECTBYRANGOFECHA);

			ps.setDate(1, inicio);
			ps.setDate(2, fin);

			ResultSet rs = ps.executeQuery();
			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			UsuarioDAO usuarioDAO = fabricaMySQL.getUsuarioDAO();
			MotivoDAO motivoDAO = fabricaMySQL.getMotivoDAO();

			ArrayList<BitacoraAccesoTO> coleccion = null;

			while (rs.next()) {
				if (coleccion == null)
					coleccion = new ArrayList<BitacoraAccesoTO>();

				int idOperacion = rs.getInt("id_operacion");
				java.sql.Date fecha = rs.getDate("fecha");
				java.sql.Time hora = rs.getTime("hora");

				ArrayList<UsuarioTO> listUsuarioTO = new ArrayList<UsuarioTO>();
				ArrayList<MotivoTO> listMotivoTO = new ArrayList<MotivoTO>();
				UsuarioTO usuarioTO = usuarioDAO.findUsuarioById(rs
						.getInt("id_usuario"));
				MotivoTO motivoTO = motivoDAO.findMotivoById(rs
						.getInt("id_motivo"));
				listUsuarioTO.add(usuarioTO);
				listMotivoTO.add(motivoTO);

				UsuarioTO[] arrUsuarioTO = (UsuarioTO[]) listUsuarioTO
						.toArray(new UsuarioTO[listUsuarioTO.size()]);
				MotivoTO[] arrMotivoTO = (MotivoTO[]) listMotivoTO
						.toArray(new MotivoTO[listMotivoTO.size()]);

				BitacoraAccesoTO bitacoraAccesoTO = new BitacoraAccesoTO(
						idOperacion, fecha, hora, arrUsuarioTO, arrMotivoTO);

				coleccion.add(bitacoraAccesoTO);
			}
			ps.close();
			conexion.close();

			return coleccion;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public ArrayList<BitacoraAccesoTO> selectByRangoFechaHora(Date inicioFecha,
			Date finFecha, Time inicioHora, Time finHora) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion
					.prepareStatement(SELECTBYRANGOFECHAHORA);

			ps.setDate(1, inicioFecha);
			ps.setDate(2, finFecha);
			ps.setTime(3, inicioHora);
			ps.setTime(4, finHora);

			ResultSet rs = ps.executeQuery();
			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			UsuarioDAO usuarioDAO = fabricaMySQL.getUsuarioDAO();
			MotivoDAO motivoDAO = fabricaMySQL.getMotivoDAO();

			ArrayList<BitacoraAccesoTO> coleccion = null;

			while (rs.next()) {
				if (coleccion == null)
					coleccion = new ArrayList<BitacoraAccesoTO>();

				int idOperacion = rs.getInt("id_operacion");
				java.sql.Date fecha = rs.getDate("fecha");
				java.sql.Time hora = rs.getTime("hora");

				ArrayList<UsuarioTO> listUsuarioTO = new ArrayList<UsuarioTO>();
				ArrayList<MotivoTO> listMotivoTO = new ArrayList<MotivoTO>();
				UsuarioTO usuarioTO = usuarioDAO.findUsuarioById(rs
						.getInt("id_usuario"));
				MotivoTO motivoTO = motivoDAO.findMotivoById(rs
						.getInt("id_motivo"));
				listUsuarioTO.add(usuarioTO);
				listMotivoTO.add(motivoTO);

				UsuarioTO[] arrUsuarioTO = (UsuarioTO[]) listUsuarioTO
						.toArray(new UsuarioTO[listUsuarioTO.size()]);
				MotivoTO[] arrMotivoTO = (MotivoTO[]) listMotivoTO
						.toArray(new MotivoTO[listMotivoTO.size()]);

				BitacoraAccesoTO bitacoraAccesoTO = new BitacoraAccesoTO(
						idOperacion, fecha, hora, arrUsuarioTO, arrMotivoTO);

				coleccion.add(bitacoraAccesoTO);
			}
			ps.close();
			conexion.close();

			return coleccion;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public BitacoraAccesoTO selectByUsuario(int idUsuario) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			UsuarioDAO usuarioDAO = null;
			MotivoDAO motivoDAO = null;

			ArrayList<Integer> listIdOperacion = null;
			ArrayList<java.sql.Date> listFecha = null;
			ArrayList<java.sql.Time> listHora = null;
			ArrayList<UsuarioTO> listUsuarioTO = null;
			ArrayList<MotivoTO> listMotivoTO = null;

			BitacoraAccesoTO bitacoraAccesoTO = null;

			PreparedStatement ps = conexion.prepareStatement(SELECTBYUSUARIO);
			ps.setInt(1, idUsuario);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (listIdOperacion == null) {

					listIdOperacion = new ArrayList<Integer>();
					listFecha = new ArrayList<java.sql.Date>();
					listHora = new ArrayList<java.sql.Time>();
					listUsuarioTO = new ArrayList<UsuarioTO>();
					listMotivoTO = new ArrayList<MotivoTO>();

					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					usuarioDAO = fabricaMySQL.getUsuarioDAO();
					motivoDAO = fabricaMySQL.getMotivoDAO();
				}
				listIdOperacion.add(rs.getInt("id_operacion"));
				listFecha.add(rs.getDate("fecha"));
				listHora.add(rs.getTime("hora"));
				listMotivoTO.add(motivoDAO.findMotivoById(rs
						.getInt("id_motivo")));
			}
			if (listIdOperacion != null) {
				listUsuarioTO.add(usuarioDAO.findUsuarioById(idUsuario));

				UsuarioTO[] arrUsuarioTO = (UsuarioTO[]) listUsuarioTO
						.toArray(new UsuarioTO[listUsuarioTO.size()]);
				MotivoTO[] arrMotivoTO = (MotivoTO[]) listMotivoTO
						.toArray(new MotivoTO[listMotivoTO.size()]);
				Date[] arrFecha = (Date[]) listFecha.toArray(new Date[listFecha
						.size()]);
				Time[] arrHora = (Time[]) listHora.toArray(new Time[listHora
						.size()]);
				Integer[] arrIdOperacion = (Integer[]) listIdOperacion
						.toArray(new Integer[listIdOperacion.size()]);

				bitacoraAccesoTO = new BitacoraAccesoTO(arrIdOperacion,
						arrFecha, arrHora, arrUsuarioTO, arrMotivoTO);
			}
			ps.close();
			conexion.close();
			return bitacoraAccesoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public BitacoraAccesoTO selectByUsuarioMotivoRangoFechaHora(int idUsuario,
			int idMotivo, Date inicioFecha, Date finFecha, Time inicioHora,
			Time finHora) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			FabricaDeDAOs fabricaMySQL = null;

			UsuarioDAO usuarioDAO = null;
			MotivoDAO motivoDAO = null;

			ArrayList<Integer> listIdOperacion = null;
			ArrayList<java.sql.Date> listFecha = null;
			ArrayList<java.sql.Time> listHora = null;
			ArrayList<UsuarioTO> listUsuarioTO = null;
			ArrayList<MotivoTO> listMotivoTO = null;

			BitacoraAccesoTO bitacoraAccesoTO = null;

			PreparedStatement ps = conexion
					.prepareStatement(SELECTBYUSUARIOMOTIVORANGOFECHAHORA);

			ps.setInt(1, idUsuario);
			ps.setInt(2, idMotivo);
			ps.setDate(3, inicioFecha);
			ps.setDate(4, finFecha);
			ps.setTime(5, inicioHora);
			ps.setTime(6, finHora);

			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (listIdOperacion == null) {

					listIdOperacion = new ArrayList<Integer>();
					listFecha = new ArrayList<java.sql.Date>();
					listHora = new ArrayList<java.sql.Time>();
					listUsuarioTO = new ArrayList<UsuarioTO>();
					listMotivoTO = new ArrayList<MotivoTO>();

					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					usuarioDAO = fabricaMySQL.getUsuarioDAO();
					motivoDAO = fabricaMySQL.getMotivoDAO();
				}
				listIdOperacion.add(rs.getInt("id_operacion"));
				listFecha.add(rs.getDate("fecha"));
				listHora.add(rs.getTime("hora"));
				listMotivoTO.add(motivoDAO.findMotivoById(rs
						.getInt("id_motivo")));
			}
			if (listIdOperacion != null) {
				listUsuarioTO.add(usuarioDAO.findUsuarioById(idUsuario));

				UsuarioTO[] arrUsuarioTO = (UsuarioTO[]) listUsuarioTO
						.toArray(new UsuarioTO[listUsuarioTO.size()]);
				MotivoTO[] arrMotivoTO = (MotivoTO[]) listMotivoTO
						.toArray(new MotivoTO[listMotivoTO.size()]);
				Date[] arrFecha = (Date[]) listFecha.toArray(new Date[listFecha
						.size()]);
				Time[] arrHora = (Time[]) listHora.toArray(new Time[listHora
						.size()]);
				Integer[] arrIdOperacion = (Integer[]) listIdOperacion
						.toArray(new Integer[listIdOperacion.size()]);

				bitacoraAccesoTO = new BitacoraAccesoTO(arrIdOperacion,
						arrFecha, arrHora, arrUsuarioTO, arrMotivoTO);
			}
			ps.close();
			conexion.close();
			return bitacoraAccesoTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public short updateBitacoraAcceso(BitacoraAccesoTO bitacoraAccesoTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(UPDATE);

			ps.setDate(1, FechaHoraTO.getFecha(bitacoraAccesoTO.getFecha()));
			ps.setTime(2, FechaHoraTO.getHora(bitacoraAccesoTO.getHora()));
			ps.setInt(3, bitacoraAccesoTO.getIdUsuario());
			ps.setInt(4, bitacoraAccesoTO.getIdMotivo());
			ps.setInt(5, bitacoraAccesoTO.getIdOperacion());

			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			} else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}
	}

}
